home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PACKET / CBBS60SO.ZIP / MBUSER.C < prev    next >
Text File  |  1989-02-02  |  14KB  |  633 lines

  1.  
  2. /*
  3.  *  MBUSER.C - 10/30/88
  4.  */
  5.  
  6. #include "mb.h"
  7.  
  8. #define uf_inc 100    /* Headroom in user file */
  9.  
  10. char *usfile, *usbfile;
  11. USER_HDR *ufhs;
  12. USER     *tuser;
  13. char   *um[num_um];
  14. char   tcall[ln_call];
  15. short  maxusers;
  16. static char *users;
  17.  
  18. int ufl;
  19.  
  20. /*
  21.  *  Clean the user file.
  22.  *  Force drain of buffers, update of directory items.
  23.  */
  24.  
  25. clnuser()
  26. {
  27.   close(ufl);
  28.   ufl = open(usfile, O_RDWR | O_BINARY);
  29. }
  30.  
  31. /*
  32.  *  Close the user file.
  33.  */
  34.  
  35. clsusr()
  36. {
  37.   close (ufl);
  38. }
  39.  
  40. /*
  41.  *  Open the user file.
  42.  *  Allocate space for the user file records.
  43.  */
  44.  
  45. opnusr()
  46. {
  47.   ufhs = (USER_HDR *) malloc(sizeof(USER_HDR));
  48.  
  49.   tuser = (USER *) malloc(sizeof(USER));
  50.   tuser->rn = 0;
  51.  
  52. /*
  53.  *  Open the file. If it does not exist, make one.
  54.  */
  55.  
  56.   ufl = open(usfile, O_RDWR | O_BINARY);
  57.   if (ufl < 0)
  58.   {
  59.     ufl = open(usfile, O_CREAT | O_RDWR | O_BINARY, pmode);
  60.     if (ufl < 0) { nofile(usfile); exit(1); }
  61.     inuhdr();
  62.     write_rec(ufl, 0, (char *)ufhs);
  63.   }
  64.  
  65. /*
  66.  *  Read the user calls.
  67.  */
  68.  
  69.   read_rec(ufl, 0, (char *)ufhs);
  70.  
  71.   if (ufhs->version isnt us_version)
  72.   {
  73.     printf("Expected version %d, got version %d\n", us_version, ufhs->version);
  74.     nofile(usfile);
  75.     exit(1);
  76.   }
  77.  
  78.   maxusers = ufhs->count + uf_inc;
  79.  
  80.   users = (char *) malloc(ln_call * maxusers);
  81.   if (users is NULL) errall();
  82.  
  83.   rdusers();
  84. }
  85.  
  86. /*
  87.  *  Open the user file and read record zero
  88.  */
  89.  
  90. readusr()
  91. {
  92.   short prev_cnt;
  93.  
  94.   prev_cnt = ufhs->count;
  95.   ufl = open(usfile, O_RDWR | O_BINARY);
  96.   read_rec (ufl, 0, (char*)ufhs);
  97.   if (ufhs->count isnt prev_cnt) rdusers();
  98. }
  99.  
  100. /*
  101.  *  Read each user record, build list of calls.
  102.  */
  103.  
  104. rdusers()
  105. {
  106.   register int i;
  107.   register char *up;
  108.  
  109.   printf("%d users in %s\n", ufhs->count, usfile);
  110.  
  111.   for (i = 1, up = users; i <= ufhs->count; i++, up += ln_call)
  112.   {
  113.     read_rec(ufl, i, (char *)tuser);
  114.     strncpy(up, tuser->call, ln_call);
  115.     if (!tuser->zip) fill(tuser->zip, ' ', ln_zip);
  116.   }
  117.  
  118. }
  119.  
  120. /*
  121.  *  initialize the user file header.
  122.  */
  123.  
  124. inuhdr()
  125. {
  126.   curtim();
  127.   ufhs->count = 0;
  128.   ufhs->version = us_version;
  129.   strncpy(ufhs->date, l_date, ln_date);
  130.   strncpy(ufhs->time, l_time, ln_time);
  131.   ufhs->lmnr = mfhs->next_msg - 1;
  132.   fill (ufhs->unu, '\0', ufhsunu);
  133. }
  134.  
  135. /*
  136.  *  Do we know this user?
  137.  */
  138.  
  139. finduser(call)
  140. char *call;
  141. {
  142.   register int i;
  143.   register char *up;
  144.  
  145.   for (i = 1, up = users; i <= ufhs->count; i++, up += ln_call)
  146.   if (matchn(call, up, ln_call)) return i;
  147.  
  148.   return 0;
  149. }
  150.  
  151. /*
  152.  *  Read in a user record.
  153.  */
  154.  
  155. rduser(call, buf)
  156. char *call;
  157. USER *buf;
  158. {
  159.   register int i;
  160.  
  161.   if (i = finduser(call))
  162.   {
  163.     read_rec(ufl, i, (char *)buf);
  164.     buf->rn = i;
  165.     return i;
  166.   }
  167.  
  168. /*
  169.  *  There wasn't one, make one.
  170.  */
  171.  
  172.   curtim();
  173.  
  174.   buf->rn = 0;  /* Mark as non current record */
  175.  
  176.   strncpy(buf->call, call,   ln_call);
  177.   strncpy(buf->date, l_date, ln_date);
  178.   strncpy(buf->time, l_time, ln_time);
  179.  
  180.   buf->msg_number = 0;
  181.   buf->ssid       = 0;
  182.   buf->state      = 0;
  183.   buf->options    = 0;
  184.   buf->log_count  = 0;
  185.   buf->port       = ' ';
  186.  
  187.   ljsf(buf->handle, um[0], ln_handle);
  188.  
  189.   fill(buf->path, ' ', pathl);
  190.   *buf->path = '\0';
  191.  
  192.   fill(buf->home_bbs, ' ', ln_call);
  193.   fill(buf->zip,      ' ', ln_zip);
  194.   fill(buf->unu,        0, userunu);
  195.  
  196.   return 0;
  197. }
  198.  
  199. /*
  200.  *  Update the user record to the file.
  201.  */
  202.  
  203. upduser(buf)
  204. USER *buf;
  205. {
  206.   if (s_flag & s_dv) begin_lock();
  207.   read_rec(ufl, 0, (char*)ufhs);
  208.   if (!buf->rn)
  209.   {
  210.     if (ufhs->count >= maxusers)
  211.       {
  212.         if (s_flag & s_dv) end_lock();
  213.         return;
  214.       }
  215.     strncpy (users + (ln_call * ufhs->count), buf->call, ln_call);
  216.     buf->rn = ++ufhs->count;
  217.   }
  218.  
  219.   curtim();
  220.   strncpy(buf->date, l_date, ln_date);
  221.   strncpy(buf->time, l_time, ln_time);
  222.   if (s_flag & s_update)
  223.     {
  224.       buf->msg_number = mfhs->next_msg;
  225.       s_flag clrbit s_update;
  226.     }
  227.   buf->log_count++;
  228.   write_rec(ufl, buf->rn, (char *)buf);
  229.   write_rec(ufl, 0, (char *)ufhs);
  230.   if (s_flag & s_dv) end_lock();
  231. }
  232.  
  233. /*
  234.  *  Print info about a user.
  235.  */
  236.  
  237. puser()
  238. {
  239.   register int i;
  240.   register PORTS *p;
  241.  
  242.   pcall(tcall, port->fld[1]);
  243.   if (!(i = finduser(tcall))) { port->msg = mfind; return; }
  244.  
  245.   read_rec(ufl, i, (char *)tuser);
  246.  
  247.   if ((p = findport(tuser->port)) is NULL)
  248.     sprintf( tmp->scr, "Port %c\n", tuser->port);
  249.   else
  250.     sprintf(tmp->scr, "%s\n", p->name);
  251.   if(tuser->port isnt 'L')
  252.   {
  253.     outnb(tuser->call, ln_call);
  254.     outstr(" connected on ");
  255.     outstr(tmp->scr);
  256.   }
  257.   outnb(tuser->call, ln_call);
  258.   if (tuser->port is 'L')
  259.   {
  260.     outstr(" Linked to "); outnb(cport->user->call, ln_call);
  261.     outstr(" Through the GateWay at "); outstr(tuser->path);
  262.   }
  263.   else if (!*tuser->path)
  264.   {
  265.     outstr(" is a direct connect from "); outnb(cport->user->call, ln_call);
  266.   }
  267.   else
  268.   {
  269.     outstr(" connected to "); outnb(cport->user->call, ln_call);
  270.     outstr(" via "); outstr(tuser->path);
  271.   }
  272.   outchar('\n');
  273.  
  274.   outnb(tuser->call, ln_call);
  275.   sprintf(tmp->scr, " Last connected on %6.6s at %4.4s\n",
  276.     tuser->date, tuser->time);
  277.   outstr(tmp->scr);
  278.  
  279.   sprintf(tmp->scr, "The Last message number then was %u\n", tuser->msg_number);
  280.   outstr(tmp->scr);
  281.  
  282.   outnb(tuser->call, ln_call);
  283.   outstr("'s name is ");
  284.   outnb(tuser->handle, ln_handle);
  285.   outchar('\n');
  286.  
  287.   if (tuser->state & u_home)
  288.   {
  289.     outnb(tuser->call, ln_call);
  290.     outstr("'s home system is ");
  291.     outnb(tuser->home_bbs, ln_call);
  292.     outchar('\n');
  293.   }
  294.  
  295.   if (tuser->state & u_zip)
  296.   {
  297.     outnb(tuser->call, ln_call);
  298.     outstr("'s zip code is ");
  299.     outnb(tuser->zip, ln_zip);
  300.     outchar('\n');
  301.   }
  302. }
  303.  
  304. /*
  305.  *  Print a user record.
  306.  */
  307.  
  308. prtuser(p)
  309. USER *p;
  310. {
  311.   fill(port->cmd, ' ', 6);
  312.   if (p->options & u_local)   port->cmd[0] = 'L';
  313.   if (p->options & u_bbs)     port->cmd[1] = 'B';
  314.   if (p->options & u_expert)  port->cmd[2] = 'E';
  315.   if (p->options & u_delete)  port->cmd[3] = 'D';
  316.   if (p->options & u_sysop)   port->cmd[4] = 'S';
  317.   if (p->options & u_exclude) port->cmd[5] = 'K';
  318.   sprintf(tmp->scr,
  319.   "%6.6s %6.6s %4.4s %4d %5u %6.6s %2.2d%c%6.6s %-12.12s %6.6s\n  Path: %s\n",
  320.     p->call, p->date, p->time, p->log_count,
  321.     p->msg_number, p->home_bbs, p->ssid,
  322.     p->port, port->cmd, p->handle, p->zip, p->path);
  323.  
  324.   outstr(tmp->scr);
  325. }
  326.  
  327. /*
  328.  *  The "display users" command.
  329.  */
  330.  
  331. duser()
  332. {
  333.   register int i;
  334.   register short ok;
  335.  
  336.   if (port->flds is 1) pgst(um[2]); else
  337.   {
  338.     if ((port->fl = fopen(port->fld[1], "r")) isnt NULL)
  339.     { fclose(port->fl); port->msg = mexst; return; }
  340.     if ((port->fl = fopen(port->fld[1], "w")) is NULL)
  341.     { port->msg = mcant; return; }
  342.   }
  343.  
  344.   for (i = ufhs->count; i; i--)
  345.   {
  346.     read_rec(ufl, i, (char *)tuser);
  347.     ok = false;
  348.     switch(port->opt2)
  349.     {
  350.       case 'L' : ok = (tuser->options & u_local);  break;
  351.       case 'M' : ok = (tuser->options & u_bbs);    break;
  352.       case 'S' : ok = (tuser->options & u_sysop);  break;
  353.       case 'U' : ok = true; break;
  354.       case 'X' : ok = (tuser->options & u_exclude); break;
  355.     }
  356.  
  357.     if (ok)
  358.     {
  359.       if (port->flds is 1)
  360.       {
  361.         pghd();
  362.         prtuser(tuser);
  363.         if (pgck() is 'Q') return;
  364.         if (pgck() is 'Q') return;
  365.       }
  366.       else
  367.       {
  368.         prtuser(tuser);
  369.         fprintf(port->fl, "%s", tmp->scr);
  370.       }
  371.     }
  372.   }
  373.   if (port->flds is 1) pgdn(); else fclose(port->fl);
  374. }
  375.  
  376. /*
  377.  *  The N, NE, NH, NZ (update my user info) commands.
  378.  */
  379.  
  380. chguser()
  381. {
  382.   switch(port->opt2)
  383.   {
  384.     case ' ' : ljsf(port->user->handle, port->line + 2, ln_handle);
  385.                port->user->state setbit u_name;
  386.                break;
  387.  
  388.     case 'E' : port->user->options flipbit u_expert;
  389.                break;
  390.  
  391.     case 'H' : pcall(port->user->home_bbs, port->fld[1]);
  392.  
  393.                if (matchn(port->user->home_bbs, cport->user->call, ln_call))
  394.                  port->user->options setbit u_local;
  395.                else port->user->options clrbit u_local;
  396.  
  397.                port->user->state setbit u_home;
  398.                port->user->state clrbit u_sent;
  399.                break;
  400.  
  401.     case 'Z' : ljsf(port->user->zip, port->fld[1], ln_zip);
  402.                port->user->state setbit u_zip;
  403.                port->user->state clrbit u_sent;
  404.                break;
  405.   }
  406.   port->msg = mdone;
  407. }
  408.  
  409. /*
  410.  *  EU command with no argument.
  411.  *  Loop through all users, ask delete for each one.
  412.  */
  413.  
  414. edusera()
  415. {
  416.   register word i;
  417.  
  418.   for (i = ufhs->count; i; i--)
  419.   {
  420.     read_rec(ufl, i, (char *)tuser);
  421.     if (tuser->rn isnt i)
  422.     {
  423.       sprintf(tmp->scr, "User record %u has record # %u\n", i, tuser->rn);
  424.       tuser->rn = i;
  425.     }
  426.  
  427.     prtx(um[2]);
  428.     prtuser(tuser);
  429.  
  430.     prtx(um[3]); getcmd();
  431.     if (port->mode & gone) return;
  432.     if (port->opt1 is 'Q') return;
  433.     if (port->opt1 is 'Y')
  434.     {
  435.       tuser->options |= u_delete;
  436.       write_rec(ufl, tuser->rn, (char *)tuser);
  437.     }
  438.   }
  439. }
  440.  
  441. /*
  442.  *  Edit a user record.
  443.  */
  444.  
  445. eduser()
  446. {
  447.   register USER *u;
  448.  
  449.   pcall(tcall, port->fld[1]);
  450.   if (matchn(tcall, port->user->call, ln_call)) u = port->user;
  451.   else { u = tuser; rduser(tcall, u); }
  452.   while(*port->fld[0] isnt '\0')
  453.   {
  454.     prtuser(u);
  455.     outstr("PRIVILEGE: (D)elete, (E)xpert, (B)bs, (S)ysop, e(X)clude\n");
  456.     outstr("DATA: (C)all, ss(I)d, (N)ame, por(T), (P)ath, (H)ome, (Z)ip\n");
  457.     getcmd();
  458.     if (port->mode & gone) return;
  459.     switch(*port->fld[0])
  460.     {
  461.       case 'D' : u->options flipbit u_delete; *port->fld[0] = '\0'; break;
  462.       case 'E' : u->options flipbit u_expert; break;
  463.       case 'B' : u->options flipbit u_bbs; break;
  464.       case 'S' : u->options flipbit u_sysop; break;
  465.       case 'X' : u->options flipbit u_exclude;break;
  466.       case 'C' : if (*port->fld[1]) pcall(u->call, port->fld[1]); break;
  467.       case 'I' : u->ssid = atoi(port->fld[1]); break;
  468.       case 'N' : if (*port->fld[1])
  469.                  {
  470.                    u->state setbit u_name;
  471.                    ljsf(u->handle, port->line+2, ln_handle);
  472.                  }
  473.                  break;
  474.       case 'T' : if (*port->fld[1]) u->port = *port->fld[1]; break;
  475.       case 'P' : if (port->fld[1]) strncpy(u->path, port->fld[1], pathl);
  476.                  else *u->path = '\0'; break;
  477.       case 'H' : if (*port->fld[1])
  478.                  {
  479.                    u->state setbit u_home;
  480.                    u->state clrbit u_sent;
  481.                    pcall(u->home_bbs, port->fld[1]);
  482.                    if (matchn(u->home_bbs, cport->user->call, ln_call))
  483.                    u->options setbit u_local; else u->options clrbit u_local;
  484.                  }
  485.                  else
  486.                  {
  487.                    fill(u->home_bbs, ' ', ln_call);
  488.                    u->options clrbit u_local;
  489.                    u->state clrbit u_home;
  490.                    u->state setbit u_sent;
  491.                  }
  492.                  break;
  493.       case 'Z' : if (*port->fld[1])
  494.                  {
  495.                    u->state setbit u_zip;
  496.                    u->state clrbit u_sent;
  497.                    ljsf(u->zip, port->fld[1], ln_zip);
  498.                  }
  499.                  else
  500.                  {
  501.                    fill(u->zip, ' ', ln_zip);
  502.                    u->state clrbit u_zip;
  503.                    u->state setbit u_sent;
  504.                  }
  505.                  break;
  506.     }
  507.   }
  508.  
  509. /*
  510.  *  If this is a new user, add to the list.
  511.  */
  512.  
  513.   upduser(u);
  514. }
  515.  
  516. /*
  517.  *  Backup the user file.
  518.  */
  519.  
  520. untuser()
  521. {
  522.   register char *rp, *wp, *lp;
  523.   register int uflb;
  524.   register int incnt, inrec;
  525.  
  526.   if (sure()) return;
  527.   prtx(um[1]);
  528.   lp = tmp->scr + (RECSIZE * (scrmax / RECSIZE));
  529.   upduser(port->user);
  530.   close(ufl);
  531.   unlink(usbfile);
  532.  
  533.   if (samedir(usfile, usbfile)) rename(usfile, usbfile);
  534.   else copy(usfile, usbfile, false);
  535.  
  536.   unlink(usfile);
  537.  
  538.   ufl  = open(usfile,  O_CREAT  | O_RDWR | O_BINARY, pmode);
  539.   uflb = open(usbfile, O_RDONLY | O_BINARY);
  540.  
  541.   incnt = ufhs->count;
  542.   inuhdr();
  543.  
  544.   inrec = 1;
  545.   while(incnt)
  546.   {
  547.     for (rp = tmp->scr; (rp < lp) and incnt;)
  548.     {
  549.       incnt--;
  550.       read_rec(uflb, inrec++, rp);
  551.       if (!(((USER *)rp)->options & u_delete)) rp += RECSIZE;
  552.     }
  553.     for (wp = tmp->scr; wp < rp; wp += RECSIZE)
  554.       write_rec(ufl, ++ufhs->count, wp);
  555.   }
  556.  
  557.   write_rec(ufl, 0, (char *)ufhs);
  558.   close (uflb);
  559.   clnuser();
  560.   rdusers();
  561.   rduser(port->user->call, port->user);
  562. }
  563.  
  564. /*
  565.  *  If all ports are free, Issue the command for all ports to lockup.
  566.  *  wait for confirmation and then do the command.
  567.  */
  568.  
  569. setunt()
  570. {
  571.   byte pflg;
  572.   long l;
  573.  
  574.   if (!(s_flag & s_dv))
  575.   {
  576.     switch(port->opt2)
  577.     {
  578.       case 'A' :
  579.       case 'R' :
  580.       case 'M' : untmsg(); break;
  581.       case 'U' : untuser(); break;
  582.       default  : ;
  583.     }
  584.     return;
  585.   }
  586.  
  587. /*
  588.  *  If all windows are free issue the lock command
  589.  */
  590.  
  591.   getc_flag();
  592.   if (b_flag is window)
  593.   {
  594.     putcomd ('A', 'H');
  595.     pflg = getp_flag();
  596.     putc_flag (pflg clrbit window);
  597.   }
  598.   else
  599.   {
  600.     outstr("Other windows BUSY\n");
  601.     return;
  602.   }
  603.  
  604. /*
  605.  *  Wait for windows to confirm the lock by looking for a
  606.  *  cleared c_flag. Do the command if cleared, otherwise return.
  607.  */
  608.  
  609.   settmr( &l, 20);
  610.   while (true)
  611.   {
  612.     if (!(chktmr(l)))
  613.     {
  614.       putc_flag(0); break;
  615.     }
  616.     getc_flag();
  617.     if (c_flag  is 0)
  618.     {
  619.       switch(port->opt2)
  620.         {
  621.           case 'A' :
  622.           case 'R' :
  623.           case 'M' : untmsg(); break;
  624.           case 'U' : untuser(); break;
  625.           default  : ;
  626.         }
  627.       break;
  628.     }
  629.     switchw();
  630.   }
  631.   putcomd('\0','\0');
  632. }
  633.